/*
 * AbstractFilter.cpp
 *
 *  Created on: Dec 4, 2009
 */

#include "AbstractFilter.h"
#include <mpi.h>

AbstractFilter::AbstractFilter() {
}

AbstractFilter::~AbstractFilter() {
}

ImageEntity *AbstractFilter::apply(ImageEntity *originalImageEntity) {
	int width = originalImageEntity->getWidth();
	int height = originalImageEntity->getHeight();
	int fileSize = originalImageEntity->getFileSize();

	int **newVectorsR = NULL;
	int **newVectorsG = NULL;
	int **newVectorsB = NULL;

	if (originalImageEntity->getVectorsR() != NULL) {
		newVectorsR = new int*[height];
		for (int i = 0; i < height; i++) {
			newVectorsR[i] = new int[width];
		}

		applyFilterInVector(width, height, originalImageEntity->getVectorsR(), newVectorsR);

	}

	if (originalImageEntity->getVectorsG() != NULL) {
		newVectorsG = new int*[height];
		for (int i = 0; i < height; i++) {
			newVectorsG[i] = new int[width];
		}

		applyFilterInVector(width, height, originalImageEntity->getVectorsG(), newVectorsG);
	}

	if (originalImageEntity->getVectorsB() != NULL) {
		newVectorsB = new int*[height];
		for (int i = 0; i < height; i++) {
			newVectorsB[i] = new int[width];
		}

		applyFilterInVector(width, height, originalImageEntity->getVectorsB(), newVectorsB);
	}

	ImageEntity *image = NULL;
	int rank;
	MPI_Comm_rank ( MPI_COMM_WORLD, & rank);
	if (rank == 0) {
		image = new ImageEntity(width, height, fileSize, newVectorsR, newVectorsG, newVectorsB);
	}

	return image;
}



int AbstractFilter::getUpLeftValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int upLeftValue = 0;
	int columnIndex = i - 1;
	int lineIndex = j - 1;

	if (columnIndex > -1 && lineIndex > -1) {
		upLeftValue = vectors[columnIndex][lineIndex];
	}

	return upLeftValue;
}

int AbstractFilter::getUpCenterValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int upCenterValue = 0;
	int columnIndex = i - 1;

	if (columnIndex > -1) {
		upCenterValue = vectors[columnIndex][j];
	}

	return upCenterValue;
}
int AbstractFilter::getUpRightValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int upRightValue = 0;
	int columnIndex = i - 1;
	int lineIndex = j + 1;

	if (columnIndex > -1 && lineIndex < (int) maxWidth) {
		upRightValue = vectors[columnIndex][lineIndex];
	}

	return upRightValue;
}
int AbstractFilter::getCenterLeftValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int centerLeftValue = 0;
	int lineIndex = j - 1;

	if (lineIndex > -1) {
		centerLeftValue = vectors[i][lineIndex];
	}

	return centerLeftValue;
}
int AbstractFilter::getCenterRightValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int centerRightValue = 0;
	int lineIndex = j + 1;

	if (lineIndex < (int) maxWidth) {
		centerRightValue = vectors[i][lineIndex];
	}

	return centerRightValue;
}
int AbstractFilter::getDownLeftValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int downLeftValue = 0;
	int columnIndex = i + 1;
	int lineIndex = j - 1;

	if (columnIndex < (int) maxHeight && lineIndex > -1) {
		downLeftValue = vectors[columnIndex][lineIndex];
	}

	return downLeftValue;
}
int AbstractFilter::getDownCenterValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int downCenterValue = 0;
	int columnIndex = i + 1;

	if (columnIndex < (int) maxHeight) {
		downCenterValue = vectors[columnIndex][j];
	}

	return downCenterValue;
}
int AbstractFilter::getDownRightValue(unsigned int i, unsigned int j, unsigned int maxWidth, unsigned int maxHeight, int **vectors) const {
	int downRightValue = 0;
	int columnIndex = i + 1;
	int lineIndex = j + 1;

	if (columnIndex < (int) maxHeight && lineIndex < (int) maxWidth) {
		downRightValue = vectors[columnIndex][lineIndex];
	}

	return downRightValue;
}
